<?php
/**
 * @file classes/journal/DMDVDAO.inc.php
 *
 * Copyright (c) 2003-2012 John Willinsky
 */

define('DMVT_FIELD_MA', 'MAVT');
define('DMVT_FIELD_TEN', 'TENVT');
define('DMVT_FIELD_DVT', 'DVT');
define('DMVT_FIELD_TKVT', 'TK_VT');
define('DMVT_FIELD_TKDT', 'TK_DT');
define('DMVT_FIELD_TKGV', 'TK_GV');

define('DMVT_FIELD_NONE', null);



import ('classes.acct.DMVT');

class DMVTDAO extends DAO {

	///listmaten
	function &getSettingList($journalId, $name, $locale) {
		$name = "DMVTList";
		$cache =& $this->_getCacheList($journalId);
		$returner = $cache->get($name);
		if ($locale !== null) {
			if (!isset($returner[$locale]) || !is_array($returner)) {
				unset($returner);
				$returner = null;
				return $returner;
			}
			return $returner[$locale];
		}
		return $returner;
	}

	function &_getCacheList($journalId) {
		static $settingCacheList;
		//$journalId .= "-". $initName;
		if (!isset($settingCacheList)) {
			$settingCacheList = array();
		}

		if (!isset($settingCacheList[$journalId])) {
			$cacheManager =& CacheManager::getManager();
			$settingCacheList[$journalId] =& $cacheManager->getFileCache(
				"DMVTList", $journalId,
				array($this, '_cacheMissList')
			);

			$cacheTime = $settingCacheList[$journalId]->getCacheTime();
			$result =& $this->retrieve("SELECT last_modified FROM filecache WHERE filename = 'dmvt' LIMIT 1");
			if ($result->RecordCount() > 0 ){
				$row =& $result->GetRowAssoc(false);
				if (strtotime($row['last_modified']) > $cacheTime){
					$settingCacheList[$journalId]->flush();
				}
			}

		}

		return $settingCacheList[$journalId];
	}

	function _cacheMissList(&$cache, $id) {
		$settingCacheList =& $this->cgetListMATENVT($cache->getCacheId());
		if (!isset($settingCacheList[$id])) {
			$cache->setCache($id, null);
			return null;
		}
		return $settingCacheList[$id];
	}

	function &cgetListMATENVT($journalId){
		//getListMATENVT($journalId) {
		$result =& $this->retrieve(
				"SELECT mavt, tenvt FROM DMVT WHERE MAVT !='' ORDER BY MAVT");

		$sections = array() ;
		$sections['DMVTList'] = array();

		while (!$result->EOF) {
			$row =& $result->getRowAssoc(false);
			$sections['DMVTList'][$row['mavt']] = $row['mavt']."--".$row['tenvt'];
			unset($row);
			$result->MoveNext();
		}
		
		$cache =& $this->_getCacheList($journalId);
		$cache->setEntireCache($sections);
		return $sections;
	}
	////	///listmaten



	function &_getCache($journalId) {
		static $settingCache;
		//$journalId .= "-". $initName;
		if (!isset($settingCache)) {
			$settingCache = array();
		}

		if (!isset($settingCache[$journalId])) {
			$cacheManager =& CacheManager::getManager();
			$settingCache[$journalId] =& $cacheManager->getFileCache(
				"DMVT", $journalId,
				array($this, '_cacheMiss')
			);

			$cacheTime = $settingCache[$journalId]->getCacheTime();
			$result =& $this->retrieve("SELECT last_modified FROM filecache WHERE filename = 'dmvt' LIMIT 1");
			if ($result->RecordCount() > 0 ){
				$row =& $result->GetRowAssoc(false);
				if (strtotime($row['last_modified']) > $cacheTime)
					$settingCache[$journalId]->flush();
			}

		}

		return $settingCache[$journalId];
	}


	function &_getCacheMAVT($journalId) {
		static $settingCacheMAVT;
		//$journalId .= "-". $initName;
		if (!isset($settingCacheMAVT)) {
			$settingCacheMAVT = array();
		}

		if (!isset($settingCacheMAVT[$journalId])) {
			$cacheManager =& CacheManager::getManager();

			$settingCacheMAVT[$journalId] =& $cacheManager->getFileCache(
				"MAVT", $journalId,
				array($this, '_cacheMissMAVT')
			);

			$cacheTime = $settingCacheMAVT[$journalId]->getCacheTime();
			$result =& $this->retrieve("SELECT last_modified FROM filecache WHERE filename = 'dmvt' LIMIT 1");
			if ($result->RecordCount() > 0 ){
				$row =& $result->GetRowAssoc(false);
				if (strtotime($row['last_modified']) > $cacheTime)
					$settingCacheMAVT[$journalId]->flush();
			}

		}
		return $settingCacheMAVT[$journalId];
	}

	function &_getCacheDM($journalId) {
		static $settingCacheDM;
		//$journalId .= "-". $initName;
		if (!isset($settingCacheDM)) {
			$settingCacheDM = array();
		}

		if (!isset($settingCacheDM[$journalId])) {
			$cacheManager =& CacheManager::getManager();
			$settingCacheDM[$journalId] =& $cacheManager->getFileCache(
				"DMVT", $journalId,
				array($this, '_cacheMissDM')
			);

			$cacheTime = $settingCacheDM[$journalId]->getCacheTime();
			$result =& $this->retrieve("SELECT last_modified FROM filecache WHERE filename = 'dmvt' LIMIT 1");
			if ($result->RecordCount() > 0 ){
				$row =& $result->GetRowAssoc(false);
				if (strtotime($row['last_modified']) > $cacheTime)
					$settingCacheDM[$journalId]->flush();
			}



		}
		return $settingCacheDM[$journalId];
	}

	/**
	 * Retrieve a journal setting value.
	 * @param $journalId int
	 * @param $name string
	 * @param $locale string optional
	 * @return mixed
	 */
	function &getSetting($journalId, $init, $locale) {
		$name = "DMVT";
		$journalId .= "-". $init;
		$cache =& $this->_getCache($journalId);

		$returner = $cache->get($name);
		if ($locale !== null) {
			if (!isset($returner[$locale]) || !is_array($returner)) {
				unset($returner);
				$returner = null;
				return $returner;
			}
			return $returner[$locale];
		}
		return $returner;
	}

	function &getSettingDM($journalId, $init, $locale) {
		$name = "DMVT";
		$journalId .= "-DM". $init;
		$cache =& $this->_getCacheDM($journalId);

		$returner = $cache->get($name);
		if ($locale !== null) {
			if (!isset($returner[$locale]) || !is_array($returner)) {
				unset($returner);
				$returner = null;
				return $returner;
			}
			return $returner[$locale];
		}
		return $returner;
	}


	function &getSettingMAVT($journalId, $name, $locale) {
		$cache =& $this->_getCacheMAVT($journalId);
		$returner = $cache->get($name);
		if ($locale !== null) {
			if (!isset($returner[$locale]) || !is_array($returner)) {
				unset($returner);
				$returner = null;
				return $returner;
			}
			return $returner[$locale];
		}
		return $returner;
	}

	function _cacheMiss(&$cache, $id) {
		$settings =& $this->getDMVTSettings($cache->getCacheId());
		if (!isset($settings[$id])) {
			$cache->setCache($id, null);
			return null;
		}
		return $settings[$id];
	}


	function _cacheMissMAVT(&$cache, $id) {
		$settings =& $this->getDMVTSettingsMAVT($cache->getCacheId());
		if (!isset($settings[$id])) {
			$cache->setCache($id, null);
			return null;
		}
		return $settings[$id];
	}


	function _cacheMissDM(&$cache, $id) {
		$settings =& $this->getDMVTSettingsDM($cache->getCacheId());
		if (!isset($settings[$id])) {
			$cache->setCache($id, null);
			return null;
		}
		return $settings[$id];
	}
	/**
	 * Retrieve and cache all settings for a journal.
	 * @param $journalId int
	 * @return array
	 */
	function &getDMVTSettings($journalId) {
		$init = substr($journalId, -1) ;
		$journalSettings = array();
		$journalSettings['DMVT'] = ""; 
		$result =& $this->retrieve(
				"SELECT * FROM DMVT WHERE MAVT like '".$init."%' ORDER BY MAVT");
		$sections = "";
		$bolds = "<b>";
		$bolde = "</b>";
		$alinke  = "</a>";

		//$alinka = "<a href='javascript:void(0);' onclick='jgetmaVT(this.text)'>";
		$alinka = "<a href='javascript:void(0);' onclick='jgetmaVT(this.text";

		while (!$result->EOF) {
			$row =& $result->getRowAssoc(false);
			$pma = $row['mavt'];
			$pten = $row['tenvt'];
			$pdvt = $row['dvt'];
			$journalSettings['DMVT'] .= $bolds.$alinka.',"'.$pten.'"'.")'>".$pma.$alinke.$bolde."-".$pten."-".$pdvt."<br>";

			unset($row);
			$result->MoveNext();
		}


//		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMVTFromRow');
//
//
//		while (($section =& $sectionsIterator->next())) {
//			$pma = $section->getmavt();
//			$pten = $section->gettenvt();
//			$pdvt = $section->getdvt();
//			$journalSettings['DMVT'] .= $bolds.$alinka.',"'.$pten.'"'.")'>".$pma.$alinke.$bolde."-".$pten."-".$pdvt."<br>";
//			//unset($section);
//		}
		$cache =& $this->_getCache($journalId);
		$cache->setEntireCache($journalSettings) ;
		return $journalSettings;
	}

	function &getListMAVT($MAVT) {
		if (isset($MAVT))
			$result =& $this->retrieve(
				'SELECT MAVT FROM DMVT WHERE MAVT = ? ORDER BY MAVT', $MAVT
			);
		else
			$result =& $this->retrieve(
				"SELECT MAVT FROM DMVT WHERE MAVT !='' ORDER BY MAVT");

		$sections = array() ;

		while (!$result->EOF) {
			$row =& $result->getRowAssoc(false);
			$sections[$row['mavt']] = $row['mavt'];
			unset($row);
			$result->MoveNext();
		}
		return $sections;
	}


	function &getDMVTSettingsMAVT($journalId) {
		$journalSettings = array();
		$result =& $this->retrieve(
				"SELECT * FROM DMVT ORDER BY MAVT");

		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMVTFromRow');

		$sections = "";

		while (($section =& $sectionsIterator->next())) {
			$pma = $section->getmavt();
			//$pten = trim($section->gettenvt());
			$journalSettings['mavt'] .= $pma."-"; //.$pten."--";

		}

		$cache =& $this->_getCacheMAVT($journalId);
		$cache->setEntireCache($journalSettings) ;
		return $journalSettings;
	}

	function &getDMVTSettingsDM($journalId) {
		$init = substr($journalId, -1) ;
		$journalSettings = array();
		$journalSettings['DMVT'] = ""; 
		$result =& $this->retrieve(
				"SELECT * FROM DMVT WHERE MAVT like '".$init."%' ORDER BY MAVT");

		if ($result->RecordCount() == 0) {
			$returner = null;
			$result->Close();
			return $returner;

		} else {
			$i=0;
			while (!$result->EOF) {
				$row =& $result->getRowAssoc(false);
				$journalSettings['DMVT'][$i] = array();
				$mavt = $row['mavt'];
				$tenvt = $row['tenvt'];
				$journalSettings['DMVT'][$i]['MAVT'] = $mavt;
				$journalSettings['DMVT'][$i]['TENVT'] = $tenvt;
				$journalSettings['DMVT'][$i]['DVT'] = $row['dvt'];
				$journalSettings['DMVT'][$i]['TK_VT'] = $row['tk_vt'];
				$journalSettings['DMVT'][$i]['TK_GV'] = $row['tk_gv'];
				$journalSettings['DMVT'][$i]['TK_DT'] = $row['tk_dt'];

				$result->MoveNext();
				$i= $i+1;
			}
			$result->close();
			unset($result);

			$cache =& $this->_getCacheDM($journalId);
			$cache->setEntireCache($journalSettings);

			return $journalSettings;
		}


	}

	

	////////////////
	//var $cache;

	function z_cacheMiss(&$cache, $id) {
		$DMVT =& $this->getDMVT($id, null, false);
		$cache->setCache($id, $DMVT);
		return $DMVT;
	}

	function &z_getCache() {
		if (!isset($this->cache)) {
			$cacheManager =& CacheManager::getManager();
			$this->cache =& $cacheManager->getObjectCache('DMVT', 0, array(&$this, '_cacheMiss'));
		}
		return $this->cache;
	}



	////
 	function &getDMVT($MAVT, $DaoFac = false, $combo = false) {
		if (isset($MAVT))
			$result =& $this->retrieve(
				'SELECT * FROM DMVT WHERE MAVT = ? ORDER BY MAVT', $MAVT
			);
		else
			$result =& $this->retrieve(
				"SELECT * FROM DMVT WHERE MAVT !='' ORDER BY MAVT");

		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMVTFromRow');

		if ($DaoFac)
			return $sectionsIterator;
		else if (!$combo)
		{
			$returner = null;
			if ($result->RecordCount() != 0) {
				$returner =& $this->_returnDMVTFromRow($result->GetRowAssoc(false));
			}

			$result->Close();
			unset($result);
			return $returner;
		}


		$sections = $returner ;

		while (($section =& $sectionsIterator->next())) {
			$sections[$section->getMAVT()] = $section->getMAVT()."-".$section->gettenvt();
			unset($section);
		}
		return $sections;
	}


 	function &getDSMAVT($MAVT) {
		//
		$bolds = "<b>";
		$bolde = "</b>";
		$alinke  = "</a>";

		if (isset($MAVT))
			//$MAVT = "$MAVT%";
			$result =& $this->retrieve(
				'SELECT * FROM DMVT WHERE MAVT = ? ORDER BY MAVT', $MAVT
			);
		else
			$result =& $this->retrieve(
				"SELECT * FROM DMVT WHERE MAVT !='' ORDER BY MAVT");

		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMVTFromRow');

		//$sections = $returner ;
		$sections = "";
		$alinka = "<a href='javascript:void(0);' onclick='jgetmaVT(this.text)'>";


		while (($section =& $sectionsIterator->next())) {
			$pma = $section->getmavt();
			$pten = $section->gettenvt();
			$sections .= $bolds.$alinka.$pma.$alinke.$bolde."-".$pten;
			//unset($section);
		}
		
		return $sections;
	}
	

 	function &zgetDSMAVT($MAVT) {
		$bolds = "<b>";
		$bolde = "</b>";
		$alinke  = "</a>";

		if (isset($MAVT))
			$result =& $this->retrieve(
				'SELECT * FROM DMVT WHERE MAVT = ? ORDER BY MAVT', $MAVT
			);
		else
			$result =& $this->retrieve(
				"SELECT * FROM DMVT WHERE MAVT !='' ORDER BY MAVT");

		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMVTFromRow');

		$sections = $returner ;
		$alinka = "<a href='javascript:void(0);' onclick='jgetmaVT(this.text)'>";

		while (($section =& $sectionsIterator->next())) {
			$pma = $section->getmavt();
			$pten = $section->gettenvt();
			$sections[] = $bolds.$alinka.$pma.$alinke.$bolde."-".$pten;
			unset($section);
		}
		return $sections;
	}


	function &_returnDMVTFromRow(&$row) {
		$DMVT = new DMVT($row['mavt'], $row['tenvt']);
		return $DMVT;
	}


	function &getDMSearch($searchType = null, $search = null, $searchMatch = null) {

		$paramArray = array();
		$searchSql = '';

		$searchTypeMap = array(
			DMVT_FIELD_MA => 'DMVT.mavt',
			DMVT_FIELD_TEN => 'DMVT.tenvt',
			DMVT_FIELD_DVT => 'DMVT.dvt',
			DMVT_FIELD_TKVT => 'DMVT.tk_vt',
			DMVT_FIELD_TKDT => 'DMVT.tk_dt',
			DMVT_FIELD_TKGV => 'DMVT.tk_gv'
		);

		if (!empty($search) && isset($searchTypeMap[$searchType])) {
			$fieldName = $searchTypeMap[$searchType];
			switch ($searchMatch) {
				case 'is':
					$searchSql = "AND LOWER($fieldName) = LOWER(?)";
					$paramArray[] = $search;
					break;
				case 'contains':
					$searchSql = "AND LOWER($fieldName) LIKE LOWER(?)";
					$paramArray[] = '%' . $search . '%';
					break;
				case 'startsWith':
					$searchSql = "AND LOWER($fieldName) LIKE LOWER(?)";
					$paramArray[] = $search . '%';
					break;
			}
		}
//		elseif (!empty($search)) switch ($searchType) {
//			case USER_FIELD_USERID:
//				$searchSql = 'AND u.user_id=?';
//				$paramArray[] = $search;
//				break;
//			case USER_FIELD_INITIAL:
//				$searchSql = 'AND LOWER(u.last_name) LIKE LOWER(?)';
//				$paramArray[] = $search . '%';
//				break;
//		}

		//$searchSql .= ($sortBy?(' ORDER BY ' . $this->getSortMapping($sortBy) . ' ' . $this->getDirectionMapping($sortDirection)) : '');
		$result =& $this->retrieve(
				"SELECT * FROM DMVT WHERE MAVT !='' ". $searchSql. " ORDER BY MAVT",
			$paramArray
		);
		$returner = array();
		$i = 0;
		while (!$result->EOF) {
			
			$row = $result->GetRowAssoc(false);
			$returner[$i] = array();
			$returner[$i]['MAVT'] = $row['mavt'];
			$returner[$i]['TENVT'] = $row['tenvt'];
			$returner[$i]['DVT'] = $row['dvt'];
			$returner[$i]['TK_VT'] = $row['tk_vt'];
			$returner[$i]['TK_GV'] = $row['tk_gv'];
			$returner[$i]['TK_DT'] = $row['tk_dt'];

			$i++;
			$result->moveNext();
		}

		return $returner;
	}



	function deleteTKByMa($DMVTId) {
		return $this->update(
			'DELETE FROM DMVT WHERE MAVT = ? ',
			array($DMVTId)
			);
	}






	

	/**
	 * Retrieve a DMVT by abbreviation.
	 * @param $DMVTAbbrev string
	 * @param $locale string optional
	 * @return DMVT
	 */
	function &getDMVTByAbbrev($DMVTAbbrev, $journalId, $locale = null) {
		$sql = 'SELECT s.* FROM DMVT s, DMVT_settings l WHERE l.DMVT_id = s.DMVT_id AND l.setting_name = ? AND l.setting_value = ? AND s.journal_id = ?';
		$params = array('abbrev', $DMVTAbbrev, $journalId);
		if ($locale !== null) {
			$sql .= ' AND l.locale = ?';
			$params[] = $locale;
		}

		$result =& $this->retrieve($sql, $params);

		$returner = null;
		if ($result->RecordCount() != 0) {
			$returner =& $this->_returnDMVTFromRow($result->GetRowAssoc(false));
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Retrieve a DMVT by title.
	 * @param $DMVTTitle string
	 * @return DMVT
	 */
	function &getDMVTByTitle($DMVTTitle, $journalId, $locale = null) {
		$sql = 'SELECT s.* FROM DMVT s, DMVT_settings l WHERE l.DMVT_id = s.DMVT_id AND l.setting_name = ? AND l.setting_value = ? AND s.journal_id = ?';
		$params = array('title', $DMVTTitle, $journalId);
		if ($locale !== null) {
			$sql .= ' AND l.locale = ?';
			$params[] = $locale;
		}

		$result =& $this->retrieve($sql, $params);

		$returner = null;
		if ($result->RecordCount() != 0) {
			$returner =& $this->_returnDMVTFromRow($result->GetRowAssoc(false));
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Retrieve a DMVT by title and abbrev.
	 * @param $DMVTTitle string
	 * @param $DMVTAbbrev string
	 * @param $locale string optional
	 * @return DMVT
	 */
	function &getDMVTByTitleAndAbbrev($DMVTTitle, $DMVTAbbrev, $journalId, $locale) {
		$sql = 'SELECT s.* FROM DMVT s, DMVT_settings l1, DMVT_settings l2 WHERE l1.DMVT_id = s.DMVT_id AND l2.DMVT_id = s.DMVT_id AND l1.setting_name = ? AND l2.setting_name = ? AND l1.setting_value = ? AND l2.setting_value = ? AND s.journal_id = ?';
		$params = array('title', 'abbrev', $DMVTTitle, $DMVTAbbrev, $journalId);
		if ($locale !== null) {
			$sql .= ' AND l1.locale = ? AND l2.locale = ?';
			$params[] = $locale;
			$params[] = $locale;
		}

		$result =& $this->retrieve($sql, $params);

		$returner = null;
		if ($result->RecordCount() != 0) {
			$returner =& $this->_returnDMVTFromRow($result->GetRowAssoc(false));
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Internal function to return a DMVT object from a row.
	 * @param $row array
	 * @return DMVT
	 */

//	/**
//	 * Get the list of fields for which data can be localized.
//	 * @return array
//	 */
//	function getLocaleFieldNames() {
//		return array('title', 'abbrev', 'policy', 'identifyType');
//	}
//
//	/**
//	 * Update the localized fields for this table
//	 * @param $DMVT object
//	 */
	function updateLocaleFields(&$DMVT) {
		$this->updateDataObjectSettings('DMVT_settings', $DMVT, array(
			'DMVT_id' => $DMVT->getId()
		));
	}

	/**
	 * Insert a new DMVT.
	 * @param $DMVT DMVT
	 */
	function insertDMVT(&$DMVT) {
		$this->update(
			'INSERT INTO DMVT
				(MAVT, getDMSearchtenvt)
				VALUES
				(?, ?)',
			array(
				$DMVT->getMAVT(),
				$DMVT->gettenvt()
			)
		);

		$DMVT->setId($this->getInsertDMVTId());
		$this->updateLocaleFields($DMVT);
		return $DMVT->getId();
	}

	/**
	 * Update an existing DMVT.
	 * @param $DMVT DMVT
	 */
	function updateDMVT(&$DMVT) {
		$returner = $this->update(
			'UPDATE DMVT
				SET
					MAVT = ?,
					tenvt = ?
				WHERE MAVT = ?',
			array(
				$DMVT->getMAVT(),
				$DMVT->gettenvt(),
				$DMVT->getMAVT()
			)
		);
		$this->updateLocaleFields($DMVT);
		return $returner;
	}

	/**
	 * Delete a DMVT.
	 * @param $DMVT DMVT
	 */
	function deleteDMVT(&$DMVT) {
		return $this->deleteDMVTById($DMVT->getId(), $DMVT->getJournalId());
	}

	/**
	 * Delete a DMVT by ID.
	 * @param $DMVTId int
	 * @param $journalId int optional
	 */

	/**
	 * Delete DMVT by journal ID
	 * NOTE: This does not delete dependent entries EXCEPT from DMVT_editors. It is intended
	 * to be called only when deleting a journal.
	 * @param $journalId int
	 */
	function deleteDMVTByJournal($journalId) {
		$DMVT =& $this->getJournalDMVT($journalId);
		while (($DMVT =& $DMVT->next())) {
			$this->deleteDMVT($DMVT);
			unset($DMVT);
		}
	}

	/**
	 * Retrieve an array associating all DMVT editor IDs with
	 * arrays containing the DMVT they edit.
	 * @return array editorId => array(DMVT they edit)
	 */
	function &getEditorDMVT($journalId) {
		$returner = array();

		$result =& $this->retrieve(
			'SELECT s.*, se.user_id AS editor_id FROM DMVT_editors se, DMVT s WHERE se.DMVT_id = s.DMVT_id AND s.journal_id = se.journal_id AND s.journal_id = ?',
			$journalId
		);

		while (!$result->EOF) {
			$row = $result->GetRowAssoc(false);
			$DMVT =& $this->_returnDMVTFromRow($row);
			if (!isset($returner[$row['editor_id']])) {
				$returner[$row['editor_id']] = array($DMVT);
			} else {
				$returner[$row['editor_id']][] = $DMVT;
			}
			$result->moveNext();
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Retrieve all DMVT in which articles are currently published in
	 * the given issue.
	 * @return array
	 */
	function &getDMVTForIssue($issueId) {
		$returner = array();

		$result =& $this->retrieve(
			'SELECT DISTINCT s.*, COALESCE(o.seq, s.seq) AS DMVT_seq FROM DMVT s, published_articles pa, articles a LEFT JOIN custom_DMVT_orders o ON (a.DMVT_id = o.DMVT_id AND o.issue_id = ?) WHERE s.DMVT_id = a.DMVT_id AND pa.article_id = a.article_id AND pa.issue_id = ? ORDER BY DMVT_seq',
			array($issueId, $issueId)
		);

		while (!$result->EOF) {
			$row = $result->GetRowAssoc(false);
			$returner[] =& $this->_returnDMVTFromRow($row);
			$result->moveNext();
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Retrieve all DMVT for a journal.
	 * @return DAOResultFactory containing DMVT ordered by sequence
	 */
	function &getJournalDMVT($journalId, $rangeInfo = null) {
		$result =& $this->retrieveRange(
			'SELECT * FROM DMVT WHERE journal_id = ? ORDER BY seq',
			$journalId, $rangeInfo
		);

		$returner = new DAOResultFactory($result, $this, '_returnDMVTFromRow');
		return $returner;
	}

	/**
	 * Retrieve the IDs and titles of the DMVT for a journal in an associative array.
	 * @return array
	 */
	function &getDMVTTitles($journalId, $submittableOnly = false) {
		$DMVT = array();

		$DMVTIterator =& $this->getJournalDMVT($journalId);
		while (($DMVT =& $DMVTIterator->next())) {
			if ($submittableOnly) {
				if (!$DMVT->getEditorRestricted()) {
					$DMVT[$DMVT->getId()] = $DMVT->getLocalizedTitle();
				}
			} else {
				$DMVT[$DMVT->getId()] = $DMVT->getLocalizedTitle();
			}
			unset($DMVT);
		}

		return $DMVT;
	}

	/**
	 * Check if a DMVT exists with the specified ID.
	 * @param $DMVTId int
	 * @param $journalId int
	 * @return boolean
	 */
	function DMVTExists($DMVTId, $journalId) {
		$result =& $this->retrieve(
			'SELECT COUNT(*) FROM DMVT WHERE DMVT_id = ? AND journal_id = ?',
			array($DMVTId, $journalId)
		);
		$returner = isset($result->fields[0]) && $result->fields[0] == 1 ? true : false;

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Sequentially renumber DMVT in their sequence order.
	 * @param $journalId int
	 */
	function resequenceDMVT($journalId) {
		$result =& $this->retrieve(
			'SELECT DMVT_id FROM DMVT WHERE journal_id = ? ORDER BY seq',
			$journalId
		);

		for ($i=1; !$result->EOF; $i++) {
			list($DMVTId) = $result->fields;
			$this->update(
				'UPDATE DMVT SET seq = ? WHERE DMVT_id = ?',
				array(
					$i,
					$DMVTId
				)
			);

			$result->moveNext();
		}

		$result->close();
		unset($result);
	}

	/**
	 * Get the ID of the last inserted DMVT.
	 * @return int
	 */
	function getInsertDMVTId() {
		return $this->getInsertId('DMVT', 'DMVT_id');
	}

	/**
	 * Delete the custom ordering of an issue's DMVT.
	 * @param $issueId int
	 */
	function deleteCustomDMVTOrdering($issueId) {
		return $this->update(
			'DELETE FROM custom_DMVT_orders WHERE issue_id = ?', $issueId
		);
	}

	/**
	 * Delete a DMVT from the custom DMVT order table.
	 * @param $issueId int
	 * @param $DMVTId int
	 */
	function deleteCustomDMVT($issueId, $DMVTId) {
		$sequence = $this->getCustomDMVTOrder($issueId, $DMVTId);

		$this->update(
			'DELETE FROM custom_DMVT_orders WHERE issue_id = ? AND DMVT_id = ?', array($issueId, $DMVTId)
		);

		// Reduce the DMVT order of every successive DMVT by one
		$this->update(
			'UPDATE custom_DMVT_orders SET seq = seq - 1 WHERE issue_id = ? AND seq > ?', array($issueId, $sequence)
		);
	}

	/**
	 * Sequentially renumber custom DMVT orderings in their sequence order.
	 * @param $issueId int
	 */
	function resequenceCustomDMVTOrders($issueId) {
		$result =& $this->retrieve(
			'SELECT DMVT_id FROM custom_DMVT_orders WHERE issue_id = ? ORDER BY seq',
			$issueId
		);

		for ($i=1; !$result->EOF; $i++) {
			list($DMVTId) = $result->fields;
			$this->update(
				'UPDATE custom_DMVT_orders SET seq = ? WHERE DMVT_id = ? AND issue_id = ?',
				array($i, $DMVTId, $issueId)
			);

			$result->moveNext();
		}

		$result->close();
		unset($result);
	}

	/**
	 * Check if an issue has custom DMVT ordering.
	 * @param $issueId int
	 * @return boolean
	 */
	function customDMVTOrderingExists($issueId) {
		$result =& $this->retrieve(
			'SELECT COUNT(*) FROM custom_DMVT_orders WHERE issue_id = ?',
			$issueId
		);
		$returner = isset($result->fields[0]) && $result->fields[0] == 0 ? false : true;

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Get the custom DMVT order of a DMVT.
	 * @param $issueId int
	 * @param $DMVTId int
	 * @return int
	 */
	function getCustomDMVTOrder($issueId, $DMVTId) {
		$result =& $this->retrieve(
			'SELECT seq FROM custom_DMVT_orders WHERE issue_id = ? AND DMVT_id = ?',
			array($issueId, $DMVTId)
		);

		$returner = null;
		if (!$result->EOF) {
			list($returner) = $result->fields;
		}
		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Import the current DMVT orders into the specified issue as custom
	 * issue orderings.
	 * @param $issueId int
	 */
	function setDefaultCustomDMVTOrders($issueId) {
		$result =& $this->retrieve(
			'SELECT s.DMVT_id FROM DMVT s, issues i WHERE i.journal_id = s.journal_id AND i.issue_id = ? ORDER BY seq',
			$issueId
		);

		for ($i=1; !$result->EOF; $i++) {
			list($DMVTId) = $result->fields;
			$this->insertCustomDMVTOrder($issueId, $DMVTId, $i);
			$result->moveNext();
		}

		$result->close();
		unset($result);
	}

	/**
	 * INTERNAL USE ONLY: Insert a custom DMVT ordering
	 * @param $issueId int
	 * @param $DMVTId int
	 * @param $seq int
	 */
	function insertCustomDMVTOrder($issueId, $DMVTId, $seq) {
		$this->update(
			'INSERT INTO custom_DMVT_orders (DMVT_id, issue_id, seq) VALUES (?, ?, ?)',
			array(
				$DMVTId,
				$issueId,
				$seq
			)
		);
	}

	/**
	 * Move a custom issue ordering up or down, resequencing as necessary.
	 * @param $issueId int
	 * @param $DMVTId int
	 * @param $newPos int The new position (0-based) of this DMVT
	 * @param $up boolean Whether we're moving the DMVT up or down
	 */
	function moveCustomDMVTOrder($issueId, $DMVTId, $newPos, $up) {
		$this->update(
			'UPDATE custom_DMVT_orders SET seq = ? ' . ($up?'-':'+') . ' 0.5 WHERE issue_id = ? AND DMVT_id = ?',
			array($newPos, $issueId, $DMVTId)
		);
		$this->resequenceCustomDMVTOrders($issueId);
	}
}

?>
